package com.ecoolex.ying.space.core.manager;

import com.alibaba.fastjson.JSON;
import com.ecoolex.framework.common.pojo.Page;
import com.ecoolex.framework.common.pojo.Pagination;
import com.ecoolex.framework.common.util.Check;
import com.ecoolex.framework.common.util.CollectorUtil;
import com.ecoolex.ying.space.core.dao.PickGoodsLabelAssociateDAO;
import com.ecoolex.ying.space.entity.PickGoods;
import com.ecoolex.ying.space.entity.PickGoodsLabelAssociate;
import com.ecoolex.ying.space.entity.PickGoodsLabelAssociateExample;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import static com.ecoolex.ying.space.entity.PickGoodsLabelAssociate.*;

@Service
public class PickGoodsLabelAssociateManager {
    @Autowired
    private PickGoodsLabelAssociateDAO dao;

    public long countByLabelId(Integer labelId) {
        PickGoodsLabelAssociateExample example = new PickGoodsLabelAssociateExample();
        example.createCriteria().andLabelIdEqualTo(labelId).andDeletedEqualTo(NOT_DELETED);
        return dao.countByExample(example);
    }

    void refresh(PickGoods goods, String updateUser) {
        List<PickGoodsLabelAssociate> oldList = queryByPickGoodsId(goods.getPickGoodsId());

        List<Integer> labelIds = JSON.parseArray(goods.getLabelIds(), Integer.class);
        if (Check.notNullOrEmpty(labelIds)) {
            List<Integer> distinctLabelIds = labelIds.stream().distinct().collect(Collectors.toList());
            IntStream.range(0, distinctLabelIds.size()).forEach(i -> {
                Integer labelId = distinctLabelIds.get(i);
                PickGoodsLabelAssociate old = oldList.stream().collect(CollectorUtil.first(label -> label.getLabelId().equals(labelId)));
                if (Check.notNull(old)) {
                    old.setSorting(i + 1);
                    update(old, updateUser);
                    // 移除存在的
                    oldList.remove(old);
                } else {
                    PickGoodsLabelAssociate record = new PickGoodsLabelAssociate();
                    record.setPickGoodsId(goods.getPickGoodsId());
                    record.setLabelId(labelId);
                    record.setSorting(i + 1);
                    create(record, updateUser);
                }
            });
        }

        oldList.forEach(old -> delete(old, updateUser));
    }

    private void create(PickGoodsLabelAssociate record, String createUser) {
        record.setDeleted(NOT_DELETED);
        record.setCreateUser(createUser);
        record.setCreateTime(Date.from(Instant.now()));
        record.setUpdateUser(createUser);
        record.setUpdateTime(Date.from(Instant.now()));
        dao.insert(record);
    }

    private void update(PickGoodsLabelAssociate record, String updateUser) {
        record.setUpdateUser(updateUser);
        record.setUpdateTime(Date.from(Instant.now()));
        dao.updateByPrimaryKeySelective(record,
                Column.sorting,
                Column.updateUser,
                Column.updateTime);
    }

    private void delete(PickGoodsLabelAssociate record, String updateUser) {
        record.setDeleted(IS_DELETED);
        record.setUpdateUser(updateUser);
        record.setUpdateTime(Date.from(Instant.now()));

        dao.updateByPrimaryKeySelective(record,
                Column.deleted,
                Column.updateUser,
                Column.updateTime);
    }

    void deleteByPickGoodsId(Integer goodsId, String updateUser) {
        PickGoodsLabelAssociate record = new PickGoodsLabelAssociate();
        record.setDeleted(IS_DELETED);
        record.setUpdateUser(updateUser);
        record.setUpdateTime(Date.from(Instant.now()));

        PickGoodsLabelAssociateExample example = new PickGoodsLabelAssociateExample();
        example.createCriteria().andPickGoodsIdEqualTo(goodsId).andDeletedEqualTo(NOT_DELETED);

        dao.updateByExampleSelective(record,
                example,
                Column.deleted,
                Column.updateUser,
                Column.updateTime);
    }

    public List<PickGoodsLabelAssociate> queryByPickGoodsId(Integer pickGoodsId) {
        PickGoodsLabelAssociateExample example = new PickGoodsLabelAssociateExample();
        example.createCriteria().andPickGoodsIdEqualTo(pickGoodsId).andDeletedEqualTo(NOT_DELETED);
        example.orderBy(Column.sorting.asc());
        return dao.selectByExample(example);
    }

    public Pagination<PickGoodsLabelAssociate> queryByLabelId(Integer labelId, Page page) {
        PickGoodsLabelAssociateExample example = new PickGoodsLabelAssociateExample();
        example.createCriteria().andLabelIdEqualTo(labelId).andDeletedEqualTo(NOT_DELETED);
        example.orderBy(Column.pickGoodsId.asc());

        return Pagination.create(page,
                dao.countByExample(example),
                ()->dao.selectByExample(example));
    }
}